<?php

namespace app\upload\controller;

use think\Loader;
use uploadImg\imgcompress;

class UploadFile
{
    // 后台上传图片（压缩）
    public function uploadPicture()
    {
        /* 返回标准数据 */
        $return = ['status' => 1, 'info' => '上传成功', 'data' => ''];

        $dir = './uploads/Picture/' . date('Ymd');
        if (!is_dir($dir)) mkdir($dir);

        $source = $_FILES['download']['tmp_name'];
        $type = $_FILES['download']['type'];

        $save_img = $dir . '/' . uniqid() . '.' . explode('/', $type)[1];
        $percent = 1;
        $obj = new imgcompress($source, $percent);

        $picture = model('Picture');
        $hash['md5'] = md5_file($source);
        $hash['sha1'] = sha1_file($source);
        $picture_id = $picture->field(true)->where($hash)->value("id");

        if (empty($picture_id)) {
            $res = $obj->compressImg($save_img);
            if ($res) {
                $data = [
                    'path' => substr($save_img, 1),
                    'md5' => $hash['md5'],
                    'sha1' => $hash['sha1'],
                    'create_time' => time()
                ];
                $picture_id = $picture->insertGetId($data);
            }
        }

        $info = $picture->field("id,path")->where(["id" => $picture_id])->find();
        if ($info) {
            $return['status'] = 1;
            $return['data'] = $info;
        } else {
            $return['status'] = 0;
            $return['info'] = model('Picture')->getError();
        }

        $obj->__destruct();

        return json($return);
    }

    // uni-app 上传图片
    public function uniUploadPicture()
    {
        /* 返回标准数据 */
        $return = ['result' => 1, 'msg' => '上传成功', 'data' => ''];

        $dir = './uploads/Picture/' . date('Ymd');
        if (!is_dir($dir)) mkdir($dir);

//        file_put_contents(RUNTIME_PATH . 'uni_file.log', json_encode($_FILES) . PHP_EOL, FILE_APPEND);
        $source = $_FILES['download']['tmp_name'];
        $name = $_FILES['download']['name'];

        $save_img = $dir . '/' . uniqid() . '.' . pathinfo($name, PATHINFO_EXTENSION);
        $percent = 1;

        $obj = new imgcompress($source, $percent);

        $picture = model('Picture');
        $hash['md5'] = md5_file($source);
        $hash['sha1'] = sha1_file($source);
        $picture_id = $picture->field(true)->where($hash)->value("id");

        if (empty($picture_id)) {
            $res = copy($source, $save_img);

            if ($res) {
                $data = [
                    'path' => substr($save_img, 1),
                    'md5' => $hash['md5'],
                    'sha1' => $hash['sha1'],
                    'create_time' => time()
                ];
                $picture_id = $picture->insertGetId($data);
            }
        }

        $info = $picture->field("id,path")->where(["id" => $picture_id])->find();
        $info['path'] = getHost() . $info['path'];

        if ($info) {
            $return['result'] = 1;
            $return['data'] = $info;
        } else {
            $return['result'] = 2;
            $return['msg'] = '图片上传失败';
        }

        $obj->__destruct();

        return json($return);
    }

    // 上传图片保留透明层
    public function uploadPictureKeepLucency()
    {
        Loader::import('uploadImg\imgcompress', EXTEND_PATH);

        /* 返回标准数据 */
        $return = ['status' => 1, 'info' => '上传成功', 'data' => ''];

        $dir = './uploads/Picture/' . date('Ymd');
        if (!is_dir($dir)) mkdir($dir);

        $source = $_FILES['download']['tmp_name'];
        $name = $_FILES['download']['name'];
        $save_img = $dir . '/' . uniqid() . '.' . pathinfo($name, PATHINFO_EXTENSION);
        $percent = 1;

        $obj = new imgcompress($source, $percent);

        $picture = model('Picture');
        $hash['md5'] = md5_file($source);
        $hash['sha1'] = sha1_file($source);
        $picture_id = $picture->field(true)->where($hash)->value("id");

        if (empty($picture_id)) {
            $res = $obj->uploadImgKeepLucency($save_img);
            if ($res) {
                $data = [
                    'path' => substr($save_img, 1),
                    'md5' => $hash['md5'],
                    'sha1' => $hash['sha1'],
                    'create_time' => time()
                ];
                $picture_id = $picture->insertGetId($data);
            }
        }

        $info = $picture->field("id,path")->where(["id" => $picture_id])->find();
        if ($info) {
            $return['status'] = 1;
            $return['data'] = $info;
        } else {
            $return['status'] = 0;
            $return['info'] = model('Picture')->getError();
        }

        $obj->__destruct();

        return json($return);
    }

    // 规格-属性 上传图片
    public function uploadSkuPicture()
    {
        Loader::import('uploadImg\imgcompress', EXTEND_PATH);

        /* 返回标准数据 */
        $return = ['code' => 200, 'msg' => '上传成功', 'data' => []];

        $dir = './uploads/Picture/' . date('Ymd');
        if (!is_dir($dir)) mkdir($dir);

        $source = $_FILES['file']['tmp_name'];
        $name = $_FILES['file']['name'];
        $save_img = $dir . '/' . uniqid() . '.' . pathinfo($name, PATHINFO_EXTENSION);
        $percent = 1;
        $obj = new imgcompress($source, $percent);

        $picture = model('Picture');
        $hash['md5'] = md5_file($source);
        $hash['sha1'] = sha1_file($source);
        $picture_id = $picture->field(true)->where($hash)->value("id");

        if (empty($picture_id)) {
            $res = $obj->compressImg($save_img);
            if ($res) {
                $data = [
                    'path' => substr($save_img, 1),
                    'md5' => $hash['md5'],
                    'sha1' => $hash['sha1'],
                    'create_time' => time()
                ];
                $picture_id = $picture->insertGetId($data);
            }
        }

        $info = $picture->field("id,path url")->where(["id" => $picture_id])->find();
        if ($info) {
            $return['code'] = 200;
            $return['data'] = $info;
        } else {
            $return['code'] = 0;
            $return['info'] = model('Picture')->getError();
        }

        return json($return);
    }

    // excel 上传图片
    public function uploadExcelPicture($base64_img, $suffix)
    {
        $hash['md5'] = md5_file($base64_img);
        $hash['sha1'] = sha1_file($base64_img);

        $picture = model('Picture');
        $picture_id = $picture->field(true)->where($hash)->value("id");

        if (empty($picture_id)) {
            $dir = './uploads/Picture/' . date('Ymd');
            if (!is_dir($dir)) mkdir($dir);
            $save_img = $dir . '/' . uniqid() . '.' . $suffix;

            $res = file_put_contents($save_img, file_get_contents($base64_img));
            if ($res) {
                $data = [
                    'path' => substr($save_img, 1),
                    'md5' => $hash['md5'],
                    'sha1' => $hash['sha1'],
                    'create_time' => time()
                ];
                $picture_id = $picture->insertGetId($data);
            }
        }

        return $picture_id;
    }

    // 数据导入上传文件
    public function importUploadFile()
    {
        /* 返回标准数据 */
        $return = ['status' => 1, 'info' => '上传成功', 'data' => ''];

        $error = $_FILES['download']['error'];
        if ($error === 0) {
            $dir = str_replace('\\', '/', getcwd()) . '/uploads/file/' . date('Ymd');
            if (!is_dir($dir)) mkdir($dir);

            $source = $_FILES['download']['tmp_name'];
            $name = $_FILES['download']['name'];
            $save_file = $dir . '/' . $name;

            $res = copy($source, $save_file);

            if ($res) {
                $return['status'] = 0;
                $return['info'] = '文件上传成功，准备导入数据...';
                $return['data'] = $save_file;
            } else {
                $return['status'] = 0;
                $return['info'] = '文件上传失败，请重新选择文件！';
            }
        } else {
            $return['status'] = 0;
            $return['info'] = $error;
        }

        return json($return);
    }

    // 上传文件
    public function uploadFile()
    {
        /* 返回标准数据 */
        $return = ['status' => 1, 'info' => '上传成功', 'data' => ''];

        $dir = './uploads/file/' . date('Ymd');
        if (!is_dir($dir)) mkdir($dir);

        $source = $_FILES['download']['tmp_name'];
        $name = $_FILES['download']['name'];
        $save_path = $dir . '/' . uniqid() . '.' . pathinfo($name, PATHINFO_EXTENSION);

        $error = $_FILES['download']['error'];
        $err = $this->getUploadErrorMessage($error);

        $file = model('File');
        $hash['md5'] = md5_file($source);
        $hash['sha1'] = sha1_file($source);
        $file_id = $file->field(true)->where($hash)->value("id");

        if (empty($file_id)) {
            $res = copy($source, $save_path);
            if ($res) {
                $data = [
                    'path' => substr($save_path, 1),
                    'md5' => $hash['md5'],
                    'sha1' => $hash['sha1'],
                    'create_time' => time()
                ];
                $file_id = $file->insertGetId($data);
            }
        }

        $info = $file->field("id,path")->where(["id" => $file_id])->find();
        if ($info) {
            $info['path'] = getHost() . $info['path'];

            $return['status'] = 1;
            $return['data'] = $info;
        } else {
            $return['status'] = 0;
            $return['info'] = model('File')->getError();
        }

        return json($return);
    }

    // WebUploader上传文件
    public function webUploaderUploadFile()
    {
        set_time_limit(5 * 60);
        usleep(5000);
        $targetDir = './uploads/tmp_video';                                 //存放分片临时目录
        $uploadDir = './uploads/Video/' . date('Ymd');                      //分片合并存放目录

        if (!file_exists($targetDir)) {
            mkdir($targetDir, 0777, true);
        }
        if (!file_exists($uploadDir)) {
            mkdir($uploadDir, 0777, true);
        }

        $cleanupTargetDir = true; // 移除旧文件
        $maxFileAge = 5 * 3600;

        if (isset($_REQUEST["name"])) {
            $fileName = $_REQUEST["name"];
        } elseif (!empty($_FILES)) {
            $fileName = $_FILES["file"]["name"];
        } else {
            $fileName = uniqid("file_");
        }
        $oldName = $fileName;

        $fileName = iconv('UTF-8', 'gb2312', $fileName);
        $filePath = $targetDir . '/' . $fileName;

        $chunk = isset($_REQUEST["chunk"]) ? intval($_REQUEST["chunk"]) : 0;
        $chunks = isset($_REQUEST["chunks"]) ? intval($_REQUEST["chunks"]) : 1;

        if ($cleanupTargetDir) {
            if (!is_dir($targetDir) || !$dir = opendir($targetDir)) apiReturn(2, '打开临时目录失败');

            while (($file = readdir($dir)) !== false) {
                $tmpfilePath = $targetDir . '/' . $file;

                if ($tmpfilePath == "{$filePath}_{$chunk}" || $tmpfilePath == "{$filePath}_{$chunk}") {
                    continue;
                }

                if (preg_match('/\.(part|parttmp)$/', $file) && (filemtime($tmpfilePath) < time() - $maxFileAge)) {
                    unlink($tmpfilePath);
                }
            }
            closedir($dir);
        }
        // 打开临时文件
        if (!$out = fopen("{$filePath}_{$chunk}", "wb")) apiReturn(2, '打开输出流失败');

        if (!empty($_FILES)) {
            if ($_FILES["file"]["error"] || !is_uploaded_file($_FILES["file"]["tmp_name"])) apiReturn(2, '无法移动上传的文件');

            // 读取二进制输入流并将其附加到临时文件
            if (!$in = fopen($_FILES["file"]["tmp_name"], "rb")) apiReturn(2, '打开输入流失败');
        } else {
            if (!$in = fopen("php://input", "rb")) apiReturn(2, '打开输入流失败');
        }
        while ($buff = fread($in, 4096)) {
            fwrite($out, $buff);
        }
        fclose($out);
        fclose($in);
        rename("{$filePath}_{$chunk}", "{$filePath}_{$chunk}");

        $index = 0;
        $done = true;
        for ($index = 0; $index < $chunks; $index++) {
            if (!file_exists("{$filePath}_{$index}")) {
                $done = false;
                break;
            }
        }

        if ($done) {
            $pathInfo = pathinfo($fileName);
            $hashStr = substr(md5($pathInfo['basename']), 8, 16);
            $hashName = time() . $hashStr . '.' . $pathInfo['extension'];
            $uploadPath = $uploadDir . '/' . $hashName;
            if (!$out = fopen($uploadPath, "wb")) apiReturn(2, '打开输入流失败');

            // flock($hander,LOCK_EX)文件锁
            if (flock($out, LOCK_EX)) {
                for ($index = 0; $index < $chunks; $index++) {
                    if (!$in = fopen("{$filePath}_{$index}", "rb")) {
                        break;
                    }
                    while ($buff = fread($in, 4096)) {
                        fwrite($out, $buff);
                    }
                    fclose($in);
                    unlink("{$filePath}_{$index}");
                }
                flock($out, LOCK_UN);
            }
            fclose($out);

            $path = substr($uploadPath, 1);

            $data = [
                'path' => $path,
                'create_time' => time()
            ];
            $file_id = model('File')->insertGetId($data);

            $data = [
                'id' => $file_id,
                'path' => $path
            ];

            apiReturn(1, '文件上传成功', $data);
        }

        apiReturn(3, '分片上传成功');
    }

    public function getUploadErrorMessage($errorCode)
    {
        $errors = [
            UPLOAD_ERR_OK => '上传成功',
            UPLOAD_ERR_INI_SIZE => '上传的文件超过了 php.ini 中 upload_max_filesize 选项限制的值',
            UPLOAD_ERR_FORM_SIZE => '上传的文件超过了 HTML 表单中 MAX_FILE_SIZE 选项指定的值',
            UPLOAD_ERR_PARTIAL => '文件只有部分被上传',
            UPLOAD_ERR_NO_FILE => '没有文件被上传',
            UPLOAD_ERR_NO_TMP_DIR => '找不到临时文件夹',
            UPLOAD_ERR_CANT_WRITE => '文件写入失败',
            UPLOAD_ERR_EXTENSION => '文件上传被扩展程序中断',
        ];
        return $errors[$errorCode] ?? '未知错误';
    }

}